#include "Pch.h"
#include "TriangleBufferImporter.h"

#include "FbxFile.h"
#include "FbxMeshAdaptors.h"
#include "FbxNodeAdaptors.h"

#include <vector>

namespace IS
{
namespace
{

TriangleBuffer* importFbxMesh(KFbxNode* meshNode)
{
	std::auto_ptr<TriangleBuffer> tribuf(new TriangleBuffer);

	FbxMeshAdaptor mesh((KFbxMesh*)meshNode->GetNodeAttribute());
	FbxNodeAdaptor node(meshNode);

	const int cFaceCnt = mesh.getFaceCount();

	tribuf->beginDefine();

	for(int iface = 0; iface < cFaceCnt; ++iface)
	{
		int hash[3];
		TriangleBuffer::Vertex vert[3];

		for(int ivert = 0; ivert < 3; ++ivert)
		{
			hash[ivert] = mesh.getKFbxMesh()->GetPolygonVertex(iface, ivert);

			double px, py, pz, nx, ny, nz, u0, v0, u1, v1, cr, cg, cb, ca;

			mesh.getPosition(iface, ivert, px, py, pz);
			mesh.getNormal(iface, ivert, nx, ny, nz);
			mesh.getUV(iface, ivert, 0, u0, v0);
			mesh.getUV(iface, ivert, 1, u1, v1);
			mesh.getVertexColor(iface, ivert, cr, cg, cb, ca);
			
			vert[ivert].pos = Vec3f((float)px, (float)py, (float)pz);
			vert[ivert].normal = Vec3f((float)nx, (float)ny, (float)nz);
			vert[ivert].uv0 = Vec2f((float)u0, (float)v0);
			vert[ivert].uv1 = Vec2f((float)u1, (float)v1);
			vert[ivert].color = Vec4f(cr, cg, cb, ca);
		}
		tribuf->defineTriangle(hash, vert);
	}

	tribuf->endDefine();

	KFbxMatrix matrix = node.getGlobalTransform(-1) * node.getGeometryTransform();

	for(int icol=0; icol<4; ++icol)
	{
		tribuf->localTransform.r0[icol] = (float)matrix.Get(0, icol);
		tribuf->localTransform.r1[icol] = (float)matrix.Get(1, icol);
		tribuf->localTransform.r2[icol] = (float)matrix.Get(2, icol);
		tribuf->localTransform.r3[icol] = (float)matrix.Get(3, icol);
	}
	tribuf->localTransform = tribuf->localTransform.transpose();

	return tribuf.release();
}

}

/** TriangleBufferImporter implementations */
TriangleBufferImporter::TriangleBufferImporter()
{
}

void TriangleBufferImporter::import(FbxFile& fbxfile, LinkList<TriangleBuffer> &outTriangleBufs)
{
	KArrayTemplate<KFbxNode*> meshNodes;
	fbxfile.scene()->FillNodeArray(meshNodes, KFbxNodeAttribute::eMESH);

	const int cMeshCnt = meshNodes.GetCount();
	for(int imesh = 0; imesh < cMeshCnt; ++imesh)
	{
		TriangleBuffer* tribuf = importFbxMesh(meshNodes.GetAt(imesh));

		if(nullptr != tribuf)
			outTriangleBufs.pushBack(*tribuf);
	}
}

}	// namespace IS
